「能只做一遍的事,那就不要做第二遍」,稱得上是工程師的核心價值觀,不僅省時省力,也可以減少程式碼來逐量提高程式運作的效能,而這樣的理念在 Python 這種物件導向程式設計 Object-oriented programming (OOP) 中,又是尤其重要。
我們可以想像自己在使用樂高積木組建一座城堡,而所有的材料(積木)都已經擁有基礎的樣式,我們只需要將這些積木組合重建,慢慢地就可以搭建出一座大型的城堡,不過難免會遇到需要客製化的時候,此時我們可以選擇重新製作一個獨一無二的積木——重新刻出一段程式碼,我們也可以用現有的積木稍作修改、加料,做出一個具有本來積木的功能,但也有自己特有功能的新積木,而這樣的過程稱作——繼承 Inheritance。
透過使用繼承,我們可以重複利用父類別(也就是原本既有的類別)的程式碼,讓子類別(也就是新創建的類別)擁有本來父類別的屬性與方法,並且以這個為基礎加入更多屬性與方法,藉此擴充一個新的類別(子類別)。
下方的程式碼是展示了我們如何通過繼承 Person
類別來創建一個新的 Student
子類別,如果翻譯成白話文,可以理解為「我們有一個 Person
(人)的父類別,而我們想要新創建 Student
(學生)的子類別,由於我們將 Student
(學生)歸類是 Person
(人)的延伸,所以它『繼承』了 Person
擁有的一切屬性與方法,並且可以擁有專屬於 Student
(學生)自己的屬性與方法。」
# 定義一個名為 Person 的程式碼
class Person:
def __init__(self, firstname, lastname, age, country, city):
self.firstname = firstname
self.lastname = lastname
self.age = age
self.country = country
self.city = city
self.skills = []
def person_info(self):
return f'{self.firstname} {self.lastname} is {self.age} years old. He lives in {self.city}, {self.country}.'
def add_skill(self, skill):
self.skills.append(skill)
# 定義一個新類別 Student,並且繼承自類別 Person
class Student(Person):
pass
s1 = Student('Jason', 'Borne', 30, 'USA', 'Chicage')
s2 = Student('Kate', 'Moss', 40, 'England', 'London')
print(s1.person_info()) # Jason Borne is 30 years old. He lives in Chicage, USA.
s1.add_skill('JavaScript')
s1.add_skill('React')
s1.add_skill('Python')
print(s1.skills) # ['JavaScript', 'React', 'Python']
print(s2.person_info()) # Kate Moss is 40 years old. He lives in London, England.
s2.add_skill('Organizing')
s2.add_skill('Marketing')
s2.add_skill('Digital Marketing')
print(s2.skills) # ['Organizing', 'Marketing', 'Digital Marketing']
透過上面的程式碼,我麼可以發現子類別 Student
並沒有任何的程式碼,甚至連 __init__()
的建構函式都沒有,但因為繼承了父類別 Person
,所以我們可以直接存取與調用 Person
所有的屬性與方法,像是屬性 self.name
或是方法 person_info
等。
有的時候,我們可能想要繼承父類別中建構函式 __init__()
的屬性,並對其中做出修改與添加,這時候我們可以使用 super()
來存取父類別原有的屬性,再進行其他屬性的新增,以上面的程式碼做舉例,父類別 Person
中並沒有 gender
(性別)這個屬性,而我們將要示範如何在子類別中,新增 gender
這個新屬性,並且覆寫本來的 person_info
方法。
class Student(Person):
def __init__ (self, firstname, lastname, age, country, city, gender):
self.gender = gender
super().__init__(firstname, lastname, age, country, city)
def person_info(self):
gender = 'He' if self.gender =='male' else 'She'
return f'{self.firstname} {self.lastname} is {self.age} years old. {gender} lives in {self.city}, {self.country}.'
s1 = Student('Jason', 'Borne', 30, 'USA', 'Chicage','male')
s2 = Student('Kate', 'Moss', 40, 'England', 'London', 'female')
print(s1.person_info()) # Jason Borne is 30 years old. He lives in Chicage, USA.
s1.add_skill('JavaScript')
s1.add_skill('React')
s1.add_skill('Python')
print(s1.skills) # ['JavaScript', 'React', 'Python']
print(s2.person_info()) # Kate Moss is 40 years old. She lives in London, England.
s2.add_skill('Organizing')
s2.add_skill('Marketing')
s2.add_skill('Digital Marketing')
print(s2.skills) # ['Organizing', 'Marketing', 'Digital Marketing']
最後兩天了!